package Day_0201.JUC;

/**
 * @author zxc
 * @date 2023/02/01 15:52
 **/
public class Synchronized_ReentrantLock {
    public static void main(String[] args) {
        /**
         * Synchronized关键字和ReentrantLock类之间的共同点和区别
         * ===>
         * 1.共同点 ：
         * （1）它们都是加锁方式同步，而且都是阻塞式的同步;
         * 也就是说当如果一个线程获得了对象锁，进入了同步块;
         * 其他访问该同步块的线程都必须阻塞在同步块外面等待，而进行线程阻塞和唤醒的代价是比较高的;
         *
         * 2.区别：
         * （1）Sychronized是Java语言的关键字;ReentrantLock是可重入锁，是Java中所实现的类;
         *  ===>
         *  a.对于Synchronized来说，它是java语言的关键字，是原生语法层面的互斥，需要jvm实现。
         *  b.而ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁，需要lock()和unlock()方法配合try/finally语句块来完成。
         *
         * （2）
         *  ===>
         *  a.Synchronized进行编译，会在同步块的前后分别形成monitorenter和monitorexit这个两个字节码指令。
         *   在执行monitorenter指令时，首先要尝试获取对象锁。
         *   如果这个对象没被锁定，或者当前线程已经拥有了那个对象锁，把锁的计算器加1，
         *   相应的，在执行monitorexit指令时会将锁计算器就减1，当计算器为0时，锁就被释放了。
         *   如果获取对象锁失败，那当前线程就要阻塞，直到对象锁被另一个线程释放为止。
         *
         *  b.由于ReentrantLock是java.util.concurrent包下提供的一套互斥锁;
         *  相比Synchronized，ReentrantLock类提供了一些高级功能，主要有以下3项：
         *  1.等待可中断，持有锁的线程长期不释放的时候，正在等待的线程可以选择放弃等待，这相当于Synchronized来说可以避免出现死锁的情况。
         *  ===》 即，设置超时时间，以避免死锁问题;（即，某个线程长时间占用锁不释放的话，超过指定时间的话，会强制释放;）
         *
         *  2.公平锁，多个线程等待同一个锁时，必须按照申请锁的时间顺序获得锁，Synchronized锁非公平锁，
         *  ReentrantLock默认的构造函数是创建的非公平锁，可以通过参数true设为公平锁，但公平锁表现的性能不是很好。
         *
         *  3.锁绑定多个条件，一个ReentrantLock对象可以同时绑定对个对象。
         *
         */
    }
}
